package com.libra.utils.concurrent;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

/**
 * 
 * ClassName: 线程池工具类 <br/>
 * date: 2018年10月17日 下午2:42:39 <br/>
 *
 * @author wangzhch
 * @version 
 * @since JDK 1.8
 */
public class ThreadPoolUtils {

	/**线程池中默认线程的个数*/
	private static int WORK_NUMBER = 5;
	
	/**队列默认的个数*/
	private static int TASK_COUNT = 100;
	
	/**工作线程组*/
	private WorkThread[] workThread;
	
	/**任务队列(阻塞队列),作为一个缓冲*/
	private final BlockingQueue<Runnable> blockingQueues;
	
	/**用户在构造这个池,希望启动的线程数*/
	private final int work_nums;
	
	public ThreadPoolUtils(){
		this(WORK_NUMBER,TASK_COUNT);
	}
	
	/**
	 * 
	 * 创建线程池，workNumber为线程池中工作线程的个数
	 *
	 * @param workNumber
	 * @param taskCount
	 */
	public ThreadPoolUtils(int workNumber, int taskCount) {
		if(workNumber <= 0 ) {
			workNumber = WORK_NUMBER;
		}
		if(taskCount <= 0 ) {
			taskCount = TASK_COUNT;
		}
		this.work_nums = workNumber;
		
		blockingQueues = new ArrayBlockingQueue<>(taskCount);
		
		workThread = new WorkThread[workNumber];
		
		for (int i = 0; i < workNumber; i++) {
			workThread[i] = new WorkThread();
			workThread[i].start();
		}
	}

	/**
	 * 
	 * execute:(执行任务,其实只是把任务加入任务队列,什么时候执行由线程池管理器决定). <br/>
	 * @author wangzhch
	 * @param runnable
	 * @since JDK 1.8
	 */
	public void execute(Runnable runnable) {
		try {
			blockingQueues.put(runnable);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 
	 * destroy:(销毁线程池,该方法保证在所有任务都完成的情况下,才销毁所有线程,否则等待任务完成才销毁). <br/>
	 * @author wangzhch
	 * @since JDK 1.8
	 */
	public void destroy() {
		System.out.println("工作线程停止工作,进行线程池销毁.....");
		for (int i = 0; i < work_nums; i++) {
			workThread[i].stopWorker();
			workThread[i] = null;
		}
		blockingQueues.clear();//清空任务队列
	}
	
	
	
	@Override
	public String toString() {
		return "WorkThread number:" + work_nums + " wait task numner:" + blockingQueues.size();
	}



	/**
	 * 
	 * ClassName: 内部类，工作线程 <br/>
	 * date: 2018年10月17日 下午4:01:38 <br/>
	 *
	 * @author wangzhch
	 * @version ThreadPoolUtils
	 * @since JDK 1.8
	 */
	private class WorkThread extends Thread{
		public void run() {
			Runnable runnable = null;
			try {
				while (!isInterrupted()) {
					runnable = blockingQueues.take();
					if(runnable != null) {
						System.out.println(getId()+" read exec :"+runnable);
						runnable.run();
					}
					runnable = null;
				}
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		
		//停止工作任务
		public void stopWorker() {
			interrupt();
		}
	}
}
